#include "SampleLightSphere.h"
#include "GLUtils.h"
#include "LogUtils.h"
#include "math.h"
#include <gtc/matrix_transform.hpp>

// 带光源球体

SampleLightSphere::SampleLightSphere() {
    m_MVPMatLoc = GL_NONE;
    m_AngleX = 0;
    m_AngleY = 0;

    m_ScaleX = 1.0f;
    m_ScaleY = 1.0f;
}

SampleLightSphere::~SampleLightSphere() {
}


void SampleLightSphere::LoadImage(NativeImage *pImage) {
    //null implement

}

void SampleLightSphere::Init() {

    char vShaderStr[] =
            "#version 300 es                          \n"
            "layout(location = 0) in vec4 vPosition;  \n"
            "layout(location = 1) in vec4 aColor;  \n"
            "out vec4 vColor;  \n"
            "uniform mat4 u_MVPMatrix;\n"
            "void main()                              \n"
            "{                                        \n"
            "   gl_Position = u_MVPMatrix * vPosition;              \n"
            "   vColor = aColor;              \n"
            "}                                        \n";

    char fShaderStr[] =
            "#version 300 es                              \n"
            "precision mediump float;                     \n"
            "in vec4 vColor;                          \n"
            "out vec4 fragColor;                          \n"
            "void main()                                  \n"
            "{                                            \n"
            "   fragColor = vColor;  \n"
            "}                                            \n";

    m_ProgramObj = GLUtils::CreateProgram(vShaderStr, fShaderStr, m_VertexShader, m_FragmentShader);

    m_MVPMatLoc = glGetUniformLocation(m_ProgramObj, "u_MVPMatrix");
    m_VerticesArray = createPositions();
    m_ColorArray = createColors();
    UpdateMVPMatrix(m_MVPMatrix, m_AngleX, m_AngleY, (float)m_ratio);
    glEnable(GL_DEPTH_TEST);
}

void SampleLightSphere::Draw() {
//    GLushort indices[6] = {0, 1, 2, 0, 2, 3};
    LOG_DEBUG("SampleLightSphere::Draw\n");

    if (m_ProgramObj == 0)
        return;

    // Use the program object
    glUseProgram(m_ProgramObj);

    // Load the vertex data
    glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 0, m_VerticesArray);
    glEnableVertexAttribArray(0);

    glVertexAttribPointer(1, 4, GL_FLOAT, GL_FALSE, 0, m_ColorArray);
    glEnableVertexAttribArray(1);

    glUniformMatrix4fv(m_MVPMatLoc, 1, GL_FALSE, &m_MVPMatrix[0][0]);
    glDrawArrays(GL_TRIANGLE_FAN, 0, circularPixCount);
//    glDrawElements(GL_TRIANGLES, sizeof(indices) / sizeof(GLushort), GL_UNSIGNED_SHORT, indices);

    glDisableVertexAttribArray(0);
    glDisableVertexAttribArray(1);
}

void SampleLightSphere::Destroy() {
    if (m_ProgramObj) {
        glDeleteProgram(m_ProgramObj);
    }
}

void SampleLightSphere::setParentViewSize(int w, int h) {
    m_ParentViewWidth = w;
    m_ParentViewHeight = h;
    m_ratio = (float)w/h;

    GLfloat x = 0.5 * w / h;
    LOG_DEBUG("SampleLightSphere::setParentViewSize w:%d h:%d x%f \n", w, h, x);

//    circularVertices[1] = circularVertices[10]  = x;
//    circularVertices[4] = circularVertices[7] = 0-x;
}
void SampleLightSphere::OnSurfaceCreated() {

}
void SampleLightSphere::OnSurfaceChanged(int width, int height) {
    setParentViewSize(width, height);
}

GLfloat*  SampleLightSphere::createPositions() {
    int index = 0;
    float radius = 0.5f;
    GLfloat* data = new GLfloat[circularPixCount*3];
    data[index++] = 0.0f;
    data[index++] = 0.0f;
    data[index++] = 0.0f;
    float angDegSpan=360.0f/(circularPixCount - 2);

    for(float i=0;i<360+angDegSpan;i+=angDegSpan){
        data[index++] = (float) (radius*sin(i*MATH_PI/180.0f));
        data[index++] = (float)(radius*cos(i*MATH_PI/180.0f));
        data[index++] = 0.0f;
    }
    LOG_DEBUG("SampleLightSphere::createPositions index:%d \n", index);

    return data;
}

GLfloat*  SampleLightSphere::createColors() {
    GLfloat* data = new GLfloat[circularPixCount*4];
    int index = 0;
    for(float i=0;i<circularPixCount; i++){
        data[index++] = 1.0f;
        data[index++] = 0.0f;
        data[index++] = 0.0f;
        data[index++] = 1.0f;
    }
    LOG_DEBUG("SampleLightSphere::createColors index:%d \n", index);

    return data;
}
void SampleLightSphere::UpdateMVPMatrix(glm::mat4 &mvpMatrix, int angleX, int angleY, float ratio)
{
    LOGCATE("CoordSystemSample::UpdateMVPMatrix angleX = %d, angleY = %d, ratio = %f", angleX, angleY, ratio);
    angleX = angleX % 360;
    angleY = angleY % 360;

    //转化为弧度角
    float radiansX = static_cast<float>(MATH_PI / 180.0f * angleX);
    float radiansY = static_cast<float>(MATH_PI / 180.0f * angleY);


    // Projection matrix
    glm::mat4 Projection = glm::ortho(-1.0f, 1.0f, -1.0f, 1.0f, 0.1f, 100.0f);
    //glm::mat4 Projection = glm::frustum(-ratio, ratio, -1.0f, 1.0f, 4.0f, 100.0f);
    //glm::mat4 Projection = glm::perspective(45.0f,ratio, 0.1f,100.f);

    // View matrix
    glm::mat4 View = glm::lookAt(
            glm::vec3(0, 0, 4), // Camera is at (0,0,1), in World Space
            glm::vec3(0, 0, 0), // and looks at the origin
            glm::vec3(0, 1, 0)  // Head is up (set to 0,-1,0 to look upside-down)
    );

    // Model matrix
    glm::mat4 Model = glm::mat4(1.0f);
    Model = glm::scale(Model, glm::vec3(m_ScaleX, m_ScaleY, 1.0f));
    Model = glm::rotate(Model, radiansX, glm::vec3(1.0f, 0.0f, 0.0f));
    Model = glm::rotate(Model, radiansY, glm::vec3(0.0f, 1.0f, 0.0f));
    Model = glm::translate(Model, glm::vec3(0.0f, 0.0f, 0.0f));

    mvpMatrix = Projection * View * Model;

}